/**
 * 
 */
package ar.com.fiuba.team2.chat;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Date;


import org.apache.axis2.AxisFault;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import ar.com.fiuba.team2.model.Chat;
import ar.com.fiuba.team2.model.MensajeChat;
import ar.com.fiuba.team2.model.MensajeChatResult;
import ar.com.fiuba.team2.model.MiembroChat;
import ar.com.fiuba.team2.model.Miembros;
import ar.com.fiuba.team2.model.Result;
import ar.com.fiuba.team2.services.IntegrationHandler;
import ar.com.fiuba.team2.services.SessionHandler;


/**
 * @author sergio
 *
 */
public class Messager {
	
	private Logger log = LogManager.getLogger(this.getClass());
	
	public Chat createChat(long scopeId, String member) throws RemoteException { // ESTA FUNCION CREA EL CHAT SINO EXISTE Y SI LA PERSONA TIENE PERMISOS, ES COORDINADOR - SI EXISTE LOGEEA AL USUARIO DEPENDIENDO EL TIPO
	
		
		Chat chat = IntegrationHandler.getInstance().getChat(scopeId);
		
		try{
		
			if (chat==null && SessionHandler.getInstance().permisoCrear(member,scopeId)){ // SI CHAT NO EXISTE Y EL QUE INVOCO LA FUNCION ES COORDINADOR LO CREO
				
				log.info("Creando nuevo Chat");
				chat = new Chat(scopeId);
				IntegrationHandler.getInstance().setChat(chat);
				log.info("Nuevo Chat" + chat.getData().getIdChat());
				
				MiembroChat miembro = new MiembroChat(member, true);
				
				if (!IntegrationHandler.getInstance().getMiembro(miembro)) {
					// PRIMERO ME FIJO SI EL MIEMBRO EXISTE EN LA BASE
					log.info("Se crea y loguea nuevo usuario");
					IntegrationHandler.getInstance().addMiembro(miembro,chat); //agrego la relacion miembro-chat
					log.info("Se creo y logueo al usuario" + miembro.getId() );
				} else {
					log.info("Se esta logeando un nuevo usuario");					
					miembro.setStatus(true); // si el usaurio existe lo logueo
					log.info("Se logeo el usuario ok" + miembro.getId());
				}
				
				chat.setLastCallTimestamp(new Date().getTime());
						
				Result myResult=new Result("200","ok");
				chat.setMeessage(myResult);
				log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
				IntegrationHandler.getInstance().saveMiembro(miembro);
				return chat;
				
				
			}else if (chat==null && !SessionHandler.getInstance().permisoCrear(member,scopeId)){
							
				
				
				chat = new Chat((long) -10); //CREO UN CHAT CON SCOPE -10 PORQUE NO EXISTE
				
				Result myResult=new Result("100","Usuario sin permisos para crear chat en el ambito");
				
				log.info("El usuario " + member + " No puede crear chat en el ambito " + scopeId);
				
				chat.setMeessage(myResult);
				
				return chat;
			}
			
			if (chat!=null && SessionHandler.getInstance().permisoEscribir(member,scopeId)){
				//SE LOGEA AL USUARIO
				
				log.info("se inicia login del usuario " + member + " en el ambito " + scopeId);
				MiembroChat miembro = new MiembroChat(member, true);

				if(!IntegrationHandler.getInstance().getMiembro(miembro)) {
					// PRIMERO ME FIJO SI EL MIEMBRO EXISTE EN LA BASE
					log.info("El miembro " + member + " no existe, se guarda ");
					IntegrationHandler.getInstance().saveMiembro(miembro); //agrego la relacion miembro-chat
				}

				log.info("El miembro " + member + " ingresa al chat al ambito: " + scopeId);
				
				if (!IntegrationHandler.getInstance().esMiembro(miembro,scopeId)){ //si no es miembro del chat lo agrego y lo logueo
					log.info("El miembro " + member + " no existe en el ambito: " + scopeId);
					miembro.setStatus(true);
					IntegrationHandler.getInstance().addMiembro(miembro, chat);
					log.info("El miembro " + member + " ingreso al chat al ambito: " + scopeId);
					
				}else{ // si es miembro solo lo logueo
					
					miembro.setStatus(true);
					log.info("El miembro " + member + " ingreso al chat al ambito: " + scopeId);
				}
				
				chat.setLastCallTimestamp(new Date().getTime());
				
				IntegrationHandler.getInstance().setChat(chat);
				IntegrationHandler.getInstance().saveMiembro(miembro); 

				Result myResult=new Result("200","ok");
				log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
				chat.setMeessage(myResult);
			
				return chat;
			}
			
		}catch(Exception e){
			chat = new Chat((long) -10);
			Result myResult=new Result("500","internal server error");
			log.error("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription(), e);
			chat.setMeessage(myResult);
			
			return chat;
		}
			
			chat.setLastCallTimestamp(new Date().getTime());
			
			//SI LLEGO ACA ES QUE SE QUIERE LOGUEAR UNA PERSONA SOLO PARA VER Y EL CHAT ESTA CREADO
			Result myResult=new Result("200","ok");
			chat.setMeessage(myResult);
			
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			
			return chat;
			
		
	}
	
	public Chat sendMessage(long chatId, String member, String message) throws RemoteException {
		
		
			Chat chat = IntegrationHandler.getInstance().getChat(chatId);
		try{
			if (chat!=null 	&& (SessionHandler.getInstance().permisoEscribir(member,chatId))){
				
				Date timeStamp = new Date();
				MiembroChat remitente = new MiembroChat(member, false);
				
				if (IntegrationHandler.getInstance().getMiembro(remitente) && !remitente.isStatus()) {
				
					Result myResult=new Result("150","Usuario no logueado");
					log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
					chat.setMeessage(myResult);
					
					return chat;
					
				}
				
				MensajeChat mensaje = new MensajeChat(remitente, message, timeStamp.getTime());
				
				remitente.addMensajes(mensaje);
				
				IntegrationHandler.getInstance().saveMensaje(mensaje, chat);
				
			}else if (chat==null){
				chat = new Chat((long) -10); //CREO UN CHAT CON SCOPE -10 PORQUE NO EXISTE
				
				Result myResult=new Result("500","Chat no existe");
				log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
				chat.setMeessage(myResult);
				
				return chat;
				
			}else if (chat!=null && !(SessionHandler.getInstance().permisoEscribir(member,chatId))){
				
				Result myResult=new Result("125","El usuario no puede escribir en este Chat");
				
				chat.setMeessage(myResult);
				log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
				return chat;
			}
			
			chat.setLastCallTimestamp(new Date().getTime());
			
			Result myResult=new Result("200","ok");
			chat.setMeessage(myResult);
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			IntegrationHandler.getInstance().setChat(chat);
			return chat;
		
		}catch(Exception e){
			chat = new Chat((long) -10);
			Result myResult=new Result("500","internal server error");
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			chat.setMeessage(myResult);
			
			return chat;
			
		}
	}

	public MensajeChatResult updateChat(long chatId, long lastCallTimestamp) throws AxisFault {
		
		
		Chat chat = IntegrationHandler.getInstance().getChat(chatId);
		
		try {
			log.info("Se solicita la actualizacion del chat: " + chatId);
			ArrayList<MensajeChat> nuevosMensajes = chat.getNewMensajes(lastCallTimestamp);
			
			chat.setLastCallTimestamp(new Date().getTime());
			
			Result myResult=new Result("200","ok");
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			MensajeChatResult mensajeResponse = new MensajeChatResult(myResult,nuevosMensajes,chat.getLastCallTimestamp());
			log.info("se actualizo ok: " + chatId);
			
			return mensajeResponse;
		}catch(Exception e){
			MensajeChatResult mensajeResponse = new MensajeChatResult(null,null,null);
			Result myResult=new Result("500","internal server error");
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			mensajeResponse.setRespuesta(myResult);
			return mensajeResponse;
		}
	}
	
	public Miembros getMembers(long chatId) throws RemoteException { //DEVUELVE SOLO LOS USUARIOS LOGUEADOS
		
		try{
			log.info("Se solicitan todos los usuarios del chat: " + chatId);
			Miembros members = IntegrationHandler.getInstance().getAllOnlineMembers(chatId);
			Result myResult=new Result("200","ok");
			members.setMeessage(myResult);
			log.info("Se entregaron todos los usuarios del chat: " + chatId );
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			return members;
		}catch(Exception e){
			
			Miembros members=new Miembros();
			Result myResult=new Result("500","internal server error");
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			members.setMeessage(myResult);
			return members;
			
		}
	}
	
	public MensajeChatResult getHistoryChat(long chatId, String idMiembro) throws AxisFault {
		
		try{
			log.info("Se solicitan los mensajes historicos del chat: " + chatId);
			Chat chat = IntegrationHandler.getInstance().getChat(chatId);
			ArrayList<MensajeChat> allMensajes = chat.getData().getLastMensajes(chat.getLastCallTimestamp());
			Result myResult=new Result("200","ok");
			MensajeChatResult mensajeResponse = new MensajeChatResult(myResult,allMensajes);
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			return mensajeResponse; //ACA NO PASO EL LastCallTimestamp PORQUE NO HACE FALTA
		}catch(Exception e){
			Result myResult=new Result("500","internal server error");
			MensajeChatResult mensajeResponse = new MensajeChatResult(myResult,null);
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			return mensajeResponse;
		}			
	}
	
	public Result logout(long chatId, String nombreMiembro) throws RemoteException {
		try{
		
			MiembroChat miembro = new MiembroChat(nombreMiembro, false);
			
			log.info("Se solicita desloguear al usuario " + nombreMiembro + " del chat: " + chatId);
			if (!IntegrationHandler.getInstance().getMiembro(miembro)) {
				
				Result myResult=new Result("175","Usuario no existe");
				log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
							
				return myResult;
				
			}
			
			if (!miembro.isStatus()){
				
				Result myResult=new Result("150","Usuario no logueado");
				log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
							
				return myResult;
				
			}
					
			miembro.setStatus(false);
			IntegrationHandler.getInstance().saveMiembro(miembro); 
			Result myResult=new Result("200","ok");
			log.info("se desloguea al usuario ok");
			return myResult;
			
		}catch(Exception e){
			
			Result myResult=new Result("500","internal server error");
			log.info("Se envia respuesta, code: " + myResult.getCode() + " mensaje: " + myResult.getDescription());
			return myResult;
		}
		
	}
	
}
